package com.kieoo.user.utils;

import com.mysql.jdbc.log.LogFactory;
import lombok.Data;
import org.apache.commons.codec.binary.Base64;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RsaUtils {

    private static Logger logger = LogManager.getLogger(RsaUtils.class);

    // Rsa 私钥,通过generateKeyPair()方法生成
    public static String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANqi3u/wD7ArP+FsUTvyxk6otuXcTipckDYGwt1JfYKMIg9pw/vwTCyhUlpOdy5b9ZG9KaUsJ41w7G6kvcKzO977CId4pFLbI2zF/dW+N8x7Z9c8kEiO11/oXpJzYT4i9Jeu7rURYDySwe4tx+DJCk+gB9l3eqChzeL56/3DK4M1AgMBAAECgYA03eM4c3znpV2Z/Z4a99ZZ2NP4+u9vsNgyKCpgZc/SjF4EChgYyH8y34NRUN3iuNvFdM8oIGgj/GU/T9iOxtY33z1Y9lskO7jhJfvnL5p9yn71xnMjhig9VGYLWyXpr4pbupxWcRtv0/ZXTZW+WHWc+WmS13ZumbEJQAidRnxnIQJBAPkDRPcDXee7wP0S2WJ7QXp/hdxEN4dBlaJ+8d+iceokd7djx71SYwB5602tf7mDVMdcQkT6rAcu7ceaD6yEe2kCQQDgxWXbbgdFrYqOqf5acwijGjsXryRxSaVuMGdSkuR+qgte2Xgi9m1MM1AkufyLUdc90h1smmIY13u2uW1BQcvtAkEAnWqZsGXqeVJSACpoTj+I9z2ii8p8J/8n7x+9HBj/VntTSxXC8UYh2+02+VYTBl2lvJnwMtcc5TWfj60u92qQ8QJBAN8KAjDj1cOGmV9HwGXwkDmI5epymS7xbX8R+PUvXh1yjyXnlhbbgUmEAZrwE3IMHBH0Vc5Ww9DywohnJ8sBh2ECQH37YGWe6ffElP9fxpJV9MNOORqVM1mNYNwzX76DfJMLXGa+n2pI/rCQcE9D16zL0q15nGKGXhCdYpT1eZsxrFM=";

    /*
     * 解密前端传入的密文（该密文通过公钥加密后又经过了base64编码）
     */
//    public static void main(String[] args) throws Exception {
//        String jm = decryptByPrivateKey("jtzgsWCTjhStQxigfaIrgZdMl4/LQMgzS9/XHa9OGr4WjOpVCMb0XT2Moa9Ep4wlnmmZf5p2cBoMUh7s4vI4WpOOTeHhzc9OBpMnftZbxdAoeNBtiDaan2rWCtQ64Zsy4KOvmRj7cENx6eVpNwe6ka4WcgyJ6ikC+b72twIizFI=" );
//        System.out.println(jm);
//    }


    /**
     * 私钥解密
     *
     * @param text 私钥
     * @param text 待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String text) throws Exception {
        return decryptByPrivateKey(privateKey, text);
    }

    /**
     * 公钥解密
     *
     * @param publicKeyString 公钥
     * @param text            待解密的信息
     * @return 解密后的文本
     */
    public static String decryptByPublicKey(String publicKeyString, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 私钥加密
     *
     * @param privateKeyString 私钥
     * @param text             待加密的信息
     * @return 加密后的文本
     */
    public static String encryptByPrivateKey(String privateKeyString, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 私钥解密
     *
     * @param privateKeyString 私钥
     * @param text             待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String privateKeyString, String text) throws Exception {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] result = cipher.doFinal(Base64.decodeBase64(text));
        return new String(result);
    }

    /**
     * 公钥加密
     *
     * @param publicKeyString 公钥
     * @param text            待加密的文本
     * @return 加密后的文本
     */
    public static String encryptByPublicKey(String publicKeyString, String text) throws Exception {
        X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] result = cipher.doFinal(text.getBytes());
        return Base64.encodeBase64String(result);
    }

    /**
     * 构建RSA密钥对
     *
     * @return 生成后的公私钥信息
     */
    public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
        // 1.初始化秘钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        // 随机数生成器
        SecureRandom sr = new SecureRandom();
        // 设置1024位长的秘钥
        keyPairGenerator.initialize(1024, sr);
        // 开始创建
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //获取公钥
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        //获取私钥
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        //对公钥进行编码
        String PUBLIC_KEY = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        logger.info("公钥=",PUBLIC_KEY);
        //对私钥进行编码
        String PRIVATE_KEY = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        logger.info("私钥=",PRIVATE_KEY);
        return new RsaKeyPair(PUBLIC_KEY, PRIVATE_KEY);
    }

    /**
     * RSA密钥对对象
     */
    @Data
    public static class RsaKeyPair {
        // 公钥,使用base64加密后数据
        private final String publicKey;
        // 私钥,使用base64加密后数据
        private final String privateKey;

//        public RsaKeyPair(String publicKey, String privateKey) {
//            this.publicKey = publicKey;
//            this.privateKey = privateKey;
//        }
    }
}
